package com.cmpe.group6.storyroad;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.ActionBar;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.cmpe.group6.storyroad.ListAdapters.MostRecentAdapter;
import com.cmpe.group6.storyroad.jsonClasses.ProfileObject;
import com.cmpe.group6.storyroad.jsonClasses.ServerResponseObject;
import com.cmpe.group6.storyroad.jsonClasses.StoryView;
import com.google.gson.Gson;

/** Activity shows the profile information of the current user.
 *
 */
public class ProfileActivity extends Activity {

	private ProfileObject profileObject;

	private Context currentContext;

	private final ArrayList<String> story_titles = new ArrayList<String>();
	private final ArrayList<String> story_ratings = new ArrayList<String>();
	private final ArrayList<String> story_tags = new ArrayList<String>();
	private final ArrayList<String> story_ids = new ArrayList<String>();

	private TextView username;
	private TextView mail;
	private TextView followerView;
	private TextView passLabel;
	private TextView passReal;
	private ImageView profilePicture;
	private ListView storyList;
	private Button changePass;
	private Button changePassFinalize;
	private EditText oldPass;
	private EditText newPass;
	private EditText reNewPass;
	private RelativeLayout changePassLayout;
	private ProgressBar progressBar;

	private String targetname;
	private ProfileTask pTask;
	private Bitmap profilePic;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_profile);
		final ActionBar bar = getActionBar();
		bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
		bar.setDisplayShowTitleEnabled(false);

		currentContext = this;

		if (getIntent().getStringExtra("targetname") == null) {
			targetname = Utils.username;
		} else {
			targetname = getIntent().getStringExtra("targetname");
		}

		username = (TextView) findViewById(R.id.profile_name);
		mail = (TextView) findViewById(R.id.mail_real);
		followerView = (TextView) findViewById(R.id.follower_count);
		passLabel = (TextView) findViewById(R.id.pass_label);
		passReal = (TextView) findViewById(R.id.pass_real);
		profilePicture = (ImageView) findViewById(R.id.profile_pic);
		storyList = (ListView) findViewById(R.id.story_list);
		changePass = (Button) findViewById(R.id.change_pass_button);
		changePassLayout = (RelativeLayout) findViewById(R.id.change_pass_holder);
		changePassFinalize = (Button) findViewById(R.id.change_pass);
		oldPass = (EditText) findViewById(R.id.old_pass);
		newPass = (EditText) findViewById(R.id.new_pass);
		reNewPass = (EditText) findViewById(R.id.new_pass_re);
		progressBar = (ProgressBar) findViewById(R.id.progressBar_profile);

		pTask = new ProfileTask();
		pTask.execute((Void) null);

		// Clicking a story on story list will direct the user to that story's
		// page.
		storyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1,
					int position, long arg3) {

				String storyId = (String) storyList.getItemAtPosition(position);
				Intent readStoryIntent = new Intent(getApplicationContext(),
						ReadStoryActivity.class);
				readStoryIntent.putExtra("story_id", storyId);
				startActivity(readStoryIntent);
			}
		});

		// Change password button reveals related fields for the change password
		// operation.
		changePass.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (changePassLayout.getVisibility() == View.VISIBLE) {
					changePassLayout.setVisibility(View.GONE);
				} else {
					changePassLayout.setVisibility(View.VISIBLE);
				}
			}
		});

		changePassFinalize.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new ChangePasswordTask().execute((Void) null);
			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	// Activating the top bar.
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.home_button:
			Intent mainIntent = new Intent(this, MainActivity.class);
			startActivity(mainIntent);
			return true;
		case R.id.recommendations_button:
			Intent recomIntent = new Intent(this, RecommendationsActivity.class);
			startActivity(recomIntent);
			return true;
		case R.id.profile_button:
			if (username.equals(targetname)) {
				return true;
			} else {
				Intent profileIntent = new Intent(this, ProfileActivity.class);
				startActivity(profileIntent);
				return true;
			}
		case R.id.search_button:
			Intent searchIntent = new Intent(this, SearchActivity.class);
			startActivity(searchIntent);
			return true;
		case R.id.following_button:
			Intent followIntent = new Intent(this, FollowingActivity.class);
			startActivity(followIntent);
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	/**
	 * Represents an asynchronous Profile task for getting a user's profile
	 * information from the server.
	 * 
	 */
	public class ProfileTask extends AsyncTask<Void, Void, Boolean> {

		@Override
		protected void onPreExecute() {
			progressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(Utils.SERVER_NAME + "GetProfile");

			try {
				// Add your data
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
				nameValuePairs.add(new BasicNameValuePair("request_type",
						"Android"));
				nameValuePairs.add(new BasicNameValuePair("username",
						Utils.username));
				nameValuePairs.add(new BasicNameValuePair("targetname",
						targetname));
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

				// Execute HTTP Post Request
				HttpResponse response = httpclient.execute(httppost);

				String jsonResponse = EntityUtils
						.toString(response.getEntity());
				Gson gson = new Gson();
				profileObject = gson
						.fromJson(jsonResponse, ProfileObject.class);
				for (int i = 0; i < profileObject.getStories().length; i++) {
					StoryView storyView = profileObject.getStories()[i];
					story_titles.add(storyView.getTitle());
					story_ratings.add(String.valueOf(storyView.getAvgRating()));
					story_tags.add(storyView.getTags());
					story_ids.add(String.valueOf(storyView.getS_id()));
				}
				URL newurl;
				try {
					newurl = new URL(profileObject.getPhotoLink());
					profilePic = BitmapFactory.decodeStream(newurl
							.openConnection().getInputStream());
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
			} catch (IOException e) {
				// TODO Auto-generated catch block
			}

			return true;
		}

		@Override
		protected void onPostExecute(final Boolean success) {

			if (!success) {
				Toast.makeText(getApplicationContext(), "Connection Error",
						Toast.LENGTH_SHORT).show();
			}
			profilePicture.setImageBitmap(profilePic);
			username.setText(profileObject.getUserName());
			mail.setText(profileObject.getEmail());
			followerView.setText("Followers: "
					+ String.valueOf(profileObject.getFollowerCount()));

			MostRecentAdapter adapter = new MostRecentAdapter(currentContext,
					story_titles, story_ratings, story_tags, story_ids);
			if (!targetname.equals(Utils.username)) {
				TextView title = (TextView) findViewById(R.id.profileTitle);
				title.setText(targetname + "'s Profile");
				changePass.setVisibility(View.GONE);
				passLabel.setVisibility(View.INVISIBLE);
				passReal.setVisibility(View.INVISIBLE);
				TextView storiesLabel = (TextView) findViewById(R.id.mystorieslabel);
				storiesLabel.setText(targetname + "'s Stories");
				Button followButton = (Button) findViewById(R.id.follow_button);
				followButton.setVisibility(View.VISIBLE);
				if (profileObject.isFollowing()) {
					followButton.setText("Unfollow");
				}
				followButton.setOnClickListener(new OnClickListener() {

					@Override
					public void onClick(View v) {
						new FollowTask().execute((Void) null);
					}
				});
			} else {
				adapter.setSelfProfile(true);
			}
			storyList.setAdapter(adapter);
			progressBar.setVisibility(View.GONE);
		}

		@Override
		protected void onCancelled() {

		}
	}

	/**
	 * Represents an asynchronous Follow task to send follow request to server.
	 * 
	 */
	public class FollowTask extends AsyncTask<Void, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Void... params) {
			DefaultHttpClient httpclient = new DefaultHttpClient();
			String operationType = "";
			if (profileObject.isFollowing()) {
				operationType = "Unfollow";
			} else {
				operationType = "Follow";
			}
			HttpPost httppost = new HttpPost(Utils.SERVER_NAME + operationType);
			ServerResponseObject responseObject = new ServerResponseObject();

			try {
				// Add your data
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
				nameValuePairs.add(new BasicNameValuePair("request_type",
						"Android"));
				nameValuePairs.add(new BasicNameValuePair("username",
						Utils.username));
				nameValuePairs.add(new BasicNameValuePair("f_username",
						targetname));
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

				// Execute HTTP Post Request
				HttpResponse response = httpclient.execute(httppost);

				String jsonResponse = EntityUtils
						.toString(response.getEntity());
				Gson gson = new Gson();
				responseObject = gson.fromJson(jsonResponse,
						ServerResponseObject.class);

			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
			} catch (IOException e) {
				// TODO Auto-generated catch block
			}
			if (responseObject.isFollowSuccess()
					|| responseObject.isUnfollowSuccess()) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		protected void onPostExecute(final Boolean success) {

			if (!success) {
				Toast.makeText(getApplicationContext(), "Connection Error",
						Toast.LENGTH_SHORT).show();
			}
			Intent restartIntent = new Intent(getApplicationContext(),
					ProfileActivity.class);
			restartIntent.putExtra("targetname", targetname);
			startActivity(restartIntent);
		}

		@Override
		protected void onCancelled() {

		}
	}

	/**
	 * Represents an asynchronous Change Password task to send change password
	 * request to server.
	 * 
	 */
	public class ChangePasswordTask extends AsyncTask<Void, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Void... params) {

			String oldPassValue = oldPass.getText().toString();
			String newPassValue = newPass.getText().toString();
			String reNewPassValue = reNewPass.getText().toString();

			if (!newPassValue.equals(reNewPassValue)) {
				this.cancel(true);
			}

			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpPost httppost = new HttpPost(Utils.SERVER_NAME
					+ "ChangePassword");
			ServerResponseObject responseObject = new ServerResponseObject();

			try {
				// Add your data
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
				nameValuePairs.add(new BasicNameValuePair("request_type",
						"Android"));
				nameValuePairs.add(new BasicNameValuePair("username",
						Utils.username));
				nameValuePairs.add(new BasicNameValuePair("old_password",
						oldPassValue));
				nameValuePairs.add(new BasicNameValuePair("new_password",
						newPassValue));
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

				// Execute HTTP Post Request
				HttpResponse response = httpclient.execute(httppost);

				String jsonResponse = EntityUtils
						.toString(response.getEntity());
				Gson gson = new Gson();
				responseObject = gson.fromJson(jsonResponse,
						ServerResponseObject.class);

			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
			} catch (IOException e) {
				// TODO Auto-generated catch block
			}
			if (responseObject.isChangePasswordSuccess()) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		protected void onPostExecute(final Boolean success) {

			if (!success) {
				Toast.makeText(getApplicationContext(),
						"Your old password was not correct.",
						Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(getApplicationContext(),
						"Password changed successfully!", Toast.LENGTH_SHORT)
						.show();
			}
		}

		@Override
		protected void onCancelled() {
			Toast.makeText(getApplicationContext(),
					"New passwords do not match!", Toast.LENGTH_SHORT).show();
		}
	}

}
